#include "../include/etcd_client.h"
#include "logger.h"
#include <iostream>
#include <sstream>
#include <curl/curl.h>
#include <json/json.h>
#include <chrono>
#include <thread>
#include <atomic>
#include "../include/base64.h"

// 用于保存CURL响应的数据结构
struct CurlResponseData {
    std::string data;
    size_t size;
};

// CURL回调函数
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    size_t realSize = size * nmemb;
    CurlResponseData* data = static_cast<CurlResponseData*>(userp);
    data->data.append(static_cast<char*>(contents), realSize);
    data->size += realSize;
    return realSize;
}

// 获取前缀的范围结束键
std::string EtcdClient::getEndKey(const std::string& prefix) {
    std::string result = prefix;
    if (result.empty()) {
        return "\xFF";
    }
    
    // 找到最后一个非0xFF字节
    size_t i = result.size() - 1;
    while (i >= 0 && static_cast<unsigned char>(result[i]) == 0xFF) {
        i--;
    }
    
    if (i < 0) {
        // 所有字节都是0xFF，无法找到更大的键
        return std::string(result.size() + 1, '\xFF');
    }
    
    // 将最后一个非0xFF字节加1
    result[i] = static_cast<char>(static_cast<unsigned char>(result[i]) + 1);
    // 截断字符串
    return result.substr(0, i + 1);
}

// EtcdClient实现
EtcdClient::EtcdClient(const std::string& url)
    : m_url(url) {
    LOG_DEBUG("创建ETCD客户端: url=" + url);
    // 初始化CURL
    curl_global_init(CURL_GLOBAL_ALL);
}

EtcdClient::~EtcdClient() {
    LOG_DEBUG("销毁ETCD客户端");
    // 清理CURL
    curl_global_cleanup();
}

// 初始化
bool EtcdClient::init() {
    LOG_INFO("初始化ETCD客户端: url=" + m_url);
    
    CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
    if (res != CURLE_OK) {
        LOG_ERROR("CURL全局初始化失败: " + std::string(curl_easy_strerror(res)));
        return false;
    }
    
    try {
        // 测试连接
        std::string healthUrl = m_url + "/health";
        std::string response;
        
        CURL* curl = curl_easy_init();
        if (!curl) {
            LOG_ERROR("初始化CURL失败");
            return false;
        }
        
        CurlResponseData responseData = {std::string(), 0};
        
        curl_easy_setopt(curl, CURLOPT_URL, healthUrl.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
        
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        
        if (res != CURLE_OK) {
            LOG_ERROR("健康检查失败: " + std::string(curl_easy_strerror(res)));
            return false;
        }
        
        try {
            Json::Value root;
            Json::Reader reader;
            if (reader.parse(responseData.data, root) && root.isMember("health") && root["health"].asString() == "true") {
                LOG_INFO("ETCD服务器健康状态良好");
                return true;
            } else {
                LOG_ERROR("ETCD服务器健康状态不佳");
                return false;
            }
        } catch (const std::exception& e) {
            LOG_ERROR("解析健康检查响应失败: " + std::string(e.what()));
            return false;
        }
    } catch (const std::exception& e) {
        LOG_ERROR("初始化ETCD客户端失败: " + std::string(e.what()));
        return false;
    }
}

// 存储键值对
EtcdResult EtcdClient::put(const std::string& key, const std::string& value, int64_t leaseId) {
    LOG_DEBUG("PUT: key=" + key + ", value=" + value + (leaseId > 0 ? ", leaseId=" + std::to_string(leaseId) : ""));
    
    EtcdResult result;
    std::string kv_url = m_url + "/v3/kv/put";
    
    Json::Value requestJson;
    requestJson["key"] = base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length());
    requestJson["value"] = base64_encode(reinterpret_cast<const unsigned char*>(value.c_str()), value.length());
    
    if (leaseId > 0) {
        requestJson["lease"] = Json::Value::UInt64(leaseId);
    }
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(kv_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        if (reader.parse(responseData.data, responseJson)) {
            result.success = true;
            if (responseJson.isMember("header")) {
                // 可以提取一些元数据
            }
        } else {
            result.success = false;
            result.errorMessage = "解析响应失败";
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 获取键值
EtcdResult EtcdClient::get(const std::string& key) {
    LOG_DEBUG("GET: key=" + key);
    
    EtcdResult result;
    std::string kv_url = m_url + "/v3/kv/range";
    
    Json::Value requestJson;
    requestJson["key"] = base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length());
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(kv_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        
        if (!reader.parse(responseData.data, responseJson)) {
            result.success = false;
            result.errorMessage = "解析响应失败";
            return result;
        }
        
        if (!responseJson.isMember("kvs") || responseJson["kvs"].size() == 0) {
            // 键不存在
            result.success = true;
            result.value = "";
            return result;
        }
        
        // 获取第一个键值对
        Json::Value firstKV = responseJson["kvs"][0];
        
        if (firstKV.isMember("value")) {
            std::string base64Value = firstKV["value"].asString();
            result.value = base64_decode(base64Value);
            result.success = true;
        } else {
            result.success = false;
            result.errorMessage = "响应中没有值字段";
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 删除键
EtcdResult EtcdClient::del(const std::string& key) {
    LOG_DEBUG("DELETE: key=" + key);
    
    EtcdResult result;
    std::string kv_url = m_url + "/v3/kv/deleterange";
    
    Json::Value requestJson;
    requestJson["key"] = base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length());
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(kv_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        
        if (reader.parse(responseData.data, responseJson)) {
            result.success = true;
            // 更安全的方式处理deleted字段
            if (responseJson.isMember("deleted")) {
                Json::Value deletedValue = responseJson["deleted"];
                // 根据不同的值类型进行处理
                if (deletedValue.isInt()) {
                    result.value = std::to_string(deletedValue.asInt());
                } else if (deletedValue.isString()) {
                    result.value = deletedValue.asString();
                } else if (deletedValue.isUInt()) {
                    result.value = std::to_string(deletedValue.asUInt());
                } else if (deletedValue.isInt64()) {
                    result.value = std::to_string(deletedValue.asInt64());
                } else if (deletedValue.isUInt64()) {
                    result.value = std::to_string(deletedValue.asUInt64());
                } else {
                    // 其他类型，直接转为字符串
                    result.value = deletedValue.toStyledString();
                }
            }
        } else {
            result.success = false;
            result.errorMessage = "解析响应失败";
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 按前缀获取键值
EtcdResult EtcdClient::getPrefix(const std::string& prefix) {
    LOG_DEBUG("GET PREFIX: prefix=" + prefix);
    
    EtcdResult result;
    std::string kv_url = m_url + "/v3/kv/range";
    
    Json::Value requestJson;
    requestJson["key"] = base64_encode(reinterpret_cast<const unsigned char*>(prefix.c_str()), prefix.length());
    
    // 设置范围结束键
    std::string rangeEnd = getEndKey(prefix);
    requestJson["range_end"] = base64_encode(reinterpret_cast<const unsigned char*>(rangeEnd.c_str()), rangeEnd.length());
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(kv_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        
        if (!reader.parse(responseData.data, responseJson)) {
            result.success = false;
            result.errorMessage = "解析响应失败";
            return result;
        }
        
        result.success = true;
        
        if (!responseJson.isMember("kvs") || responseJson["kvs"].size() == 0) {
            // 没有键值对
            return result;
        }
        
        // 提取所有键值对
        for (const auto& kv : responseJson["kvs"]) {
            if (kv.isMember("key") && kv.isMember("value")) {
                std::string key = base64_decode(kv["key"].asString());
                std::string value = base64_decode(kv["value"].asString());
                result.kvs.push_back(std::make_pair(key, value));
            }
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 创建租约
EtcdResult EtcdClient::grantLease(int ttl) {
    LOG_DEBUG("GRANT LEASE: ttl=" + std::to_string(ttl));
    
    EtcdResult result;
    std::string lease_url = m_url + "/v3/lease/grant";
    
    Json::Value requestJson;
    requestJson["TTL"] = ttl;
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(lease_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        
        if (!reader.parse(responseData.data, responseJson)) {
            result.success = false;
            result.errorMessage = "解析响应失败";
            return result;
        }
        
        if (responseJson.isMember("ID")) {
            result.success = true;
            result.value = responseJson["ID"].asString();
        } else {
            result.success = false;
            result.errorMessage = "响应中没有租约ID";
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 续约
EtcdResult EtcdClient::keepAliveLease(int64_t leaseId) {
    LOG_DEBUG("KEEP ALIVE LEASE: leaseId=" + std::to_string(leaseId));
    
    EtcdResult result;
    std::string lease_url = m_url + "/v3/lease/keepalive";
    
    Json::Value requestJson;
    requestJson["ID"] = Json::Value::UInt64(leaseId);
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(lease_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        
        if (reader.parse(responseData.data, responseJson)) {
            result.success = true;
        } else {
            result.success = false;
            result.errorMessage = "解析响应失败";
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 撤销租约
EtcdResult EtcdClient::revokeLease(int64_t leaseId) {
    LOG_DEBUG("REVOKE LEASE: leaseId=" + std::to_string(leaseId));
    
    EtcdResult result;
    std::string lease_url = m_url + "/v3/kv/lease/revoke";
    
    Json::Value requestJson;
    requestJson["ID"] = Json::Value::UInt64(leaseId);
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(lease_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
    } else {
        result.success = true;
    }
    
    return result;
}

// 执行事务
EtcdResult EtcdClient::txn(const std::string& compareKey, const std::string& compareValue, 
                          bool compareEqual, const std::string& successKey, 
                          const std::string& successValue, int64_t leaseId) {
    LOG_DEBUG("TXN: compareKey=" + compareKey + ", compareValue=" + compareValue);
    
    EtcdResult result;
    std::string txn_url = m_url + "/v3/kv/txn";
    
    Json::Value requestJson;
    
    // 比较部分
    Json::Value compare;
    Json::Value compareObj;
    compareObj["key"] = base64_encode(reinterpret_cast<const unsigned char*>(compareKey.c_str()), compareKey.length());
    compareObj["result"] = compareEqual ? "EQUAL" : "NOT_EQUAL";
    compareObj["target"] = "VALUE";
    
    if (!compareValue.empty()) {
        compareObj["value"] = base64_encode(reinterpret_cast<const unsigned char*>(compareValue.c_str()), compareValue.length());
    }
    
    compare.append(compareObj);
    requestJson["compare"] = compare;
    
    // 成功部分
    Json::Value success;
    Json::Value successObj;
    successObj["requestPut"]["key"] = base64_encode(reinterpret_cast<const unsigned char*>(successKey.c_str()), successKey.length());
    successObj["requestPut"]["value"] = base64_encode(reinterpret_cast<const unsigned char*>(successValue.c_str()), successValue.length());
    
    if (leaseId > 0) {
        successObj["requestPut"]["lease"] = Json::Value::UInt64(leaseId);
    }
    
    success.append(successObj);
    requestJson["success"] = success;
    
    // 失败部分（空）
    requestJson["failure"] = Json::Value(Json::arrayValue);
    
    Json::FastWriter writer;
    std::string requestBody = writer.write(requestJson);
    
    CurlResponseData responseData = {std::string(), 0};
    CURLcode res = performRequest(txn_url, requestBody, responseData);
    
    if (res != CURLE_OK) {
        result.success = false;
        result.errorMessage = curl_easy_strerror(res);
        return result;
    }
    
    try {
        Json::Value responseJson;
        Json::Reader reader;
        
        if (!reader.parse(responseData.data, responseJson)) {
            result.success = false;
            result.errorMessage = "解析响应失败";
            return result;
        }
        
        if (responseJson.isMember("succeeded")) {
            result.success = responseJson["succeeded"].asBool();
        } else {
            result.success = false;
            result.errorMessage = "响应中没有succeeded字段";
        }
    } catch (const std::exception& e) {
        result.success = false;
        result.errorMessage = std::string("解析响应失败: ") + e.what();
    }
    
    return result;
}

// 观察键
EtcdResult EtcdClient::watch(const std::string& key, std::function<void(const std::string&, const std::string&, bool)> callback) {
    LOG_DEBUG("WATCH: key=" + key);
    
    EtcdResult result;
    result.success = true;
    
    // 创建观察线程
    std::thread watchThread([this, key, callback]() {
        std::string watch_url = m_url + "/v3/watch";
        
        Json::Value createRequest;
        createRequest["key"] = base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length());
        
        Json::Value watchRequest;
        watchRequest["create_request"] = createRequest;
        
        Json::FastWriter writer;
        std::string requestBody = writer.write(watchRequest);
        
        // 创建CURL句柄
        CURL* curl = curl_easy_init();
        if (!curl) {
            LOG_ERROR("无法初始化CURL");
            return;
        }
        
        // 设置URL和POST数据
        curl_easy_setopt(curl, CURLOPT_URL, watch_url.c_str());
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody.c_str());
        
        // 设置回调函数
        CurlResponseData responseData = {std::string(), 0};
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
        
        // 设置HTTP头
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        
        // 执行请求
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            LOG_ERROR("Watch请求失败: " + std::string(curl_easy_strerror(res)));
        } else {
            try {
                // 处理响应
                Json::Value responseJson;
                Json::Reader reader;
                if (reader.parse(responseData.data, responseJson)) {
                    if (responseJson.isMember("result") && responseJson["result"].isMember("events")) {
                        const Json::Value& events = responseJson["result"]["events"];
                        for (unsigned int i = 0; i < events.size(); i++) {
                            const Json::Value& event = events[i];
                            std::string eventKey = base64_decode(event["kv"]["key"].asString());
                            std::string eventValue = "";
                            bool isDelete = event.isMember("type") && event["type"].asString() == "DELETE";
                            
                            if (!isDelete && event["kv"].isMember("value")) {
                                eventValue = base64_decode(event["kv"]["value"].asString());
                            }
                            
                            // 调用回调
                            callback(eventKey, eventValue, isDelete);
                        }
                    }
                }
            } catch (const std::exception& e) {
                LOG_ERROR("Watch响应解析失败: " + std::string(e.what()));
            }
        }
        
        // 清理
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    });
    
    // 分离线程，让它在后台运行
    watchThread.detach();
    
    return result;
}

// 观察前缀
EtcdResult EtcdClient::watchPrefix(const std::string& prefix, std::function<void(const std::string&, const std::string&, bool)> callback) {
    LOG_DEBUG("WATCH PREFIX: prefix=" + prefix);
    
    EtcdResult result;
    result.success = true;
    
    // 创建观察线程
    std::thread watchThread([this, prefix, callback]() {
        std::string watch_url = m_url + "/v3/watch";
        
        // 设置范围结束键
        std::string rangeEnd = getEndKey(prefix);
        
        Json::Value createRequest;
        createRequest["key"] = base64_encode(reinterpret_cast<const unsigned char*>(prefix.c_str()), prefix.length());
        createRequest["range_end"] = base64_encode(reinterpret_cast<const unsigned char*>(rangeEnd.c_str()), rangeEnd.length());
        
        Json::Value watchRequest;
        watchRequest["create_request"] = createRequest;
        
        Json::FastWriter writer;
        std::string requestBody = writer.write(watchRequest);
        
        // 创建CURL句柄
        CURL* curl = curl_easy_init();
        if (!curl) {
            LOG_ERROR("无法初始化CURL");
            return;
        }
        
        // 设置URL和POST数据
        curl_easy_setopt(curl, CURLOPT_URL, watch_url.c_str());
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody.c_str());
        
        // 设置回调函数
        CurlResponseData responseData = {std::string(), 0};
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
        
        // 设置HTTP头
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        
        // 执行请求
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            LOG_ERROR("Watch请求失败: " + std::string(curl_easy_strerror(res)));
        } else {
            try {
                // 处理响应
                Json::Value responseJson;
                Json::Reader reader;
                if (reader.parse(responseData.data, responseJson)) {
                    if (responseJson.isMember("result") && responseJson["result"].isMember("events")) {
                        const Json::Value& events = responseJson["result"]["events"];
                        for (unsigned int i = 0; i < events.size(); i++) {
                            const Json::Value& event = events[i];
                            std::string eventKey = base64_decode(event["kv"]["key"].asString());
                            std::string eventValue = "";
                            bool isDelete = event.isMember("type") && event["type"].asString() == "DELETE";
                            
                            if (!isDelete && event["kv"].isMember("value")) {
                                eventValue = base64_decode(event["kv"]["value"].asString());
                            }
                            
                            // 调用回调
                            callback(eventKey, eventValue, isDelete);
                        }
                    }
                }
            } catch (const std::exception& e) {
                LOG_ERROR("Watch响应解析失败: " + std::string(e.what()));
            }
        }
        
        // 清理
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    });
    
    // 分离线程，让它在后台运行
    watchThread.detach();
    
    return result;
}

// 执行HTTP请求
CURLcode EtcdClient::performRequest(const std::string& url, const std::string& requestBody, CurlResponseData& responseData) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        return CURLE_FAILED_INIT;
    }
    
    struct curl_slist* headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
    
    CURLcode res = curl_easy_perform(curl);
    
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    
    return res;
} 